﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web.DomainServices;
using System.ComponentModel.DataAnnotations;

namespace FlexiCommerce.Components
{
    [Serializable, DebuggerDisplay("#{ID}")]
    public abstract class PersistenceItem
    {

                /// <summary>Gets or sets the detail or property with the supplied name. If a property with the supplied name exists this is always returned in favour of any detail that might have the same name.</summary>
        /// <param name="detailName">The name of the propery or detail.</param>
        /// <returns>The value of the property or detail. If now property exists null is returned.</returns>
        public virtual object this[string detailName]
        {
            get
            {
                if (detailName == null)
                    throw new ArgumentNullException("detailName");
                switch (detailName)
                {
                    case "ID":
                        return ID;
                    default:
                        return null;
                }
            }
            set
            {
                if (string.IsNullOrEmpty(detailName))
                    throw new ArgumentNullException("Parameter 'detailName' cannot be null or empty.", "detailName");
                PropertyInfo info = GetType().GetProperty(detailName);
                if (info != null && info.CanWrite)
                {
                    if (value != null && info.PropertyType != value.GetType())
                        value = Utility.Convert(value, info.PropertyType);
                    info.SetValue(this, value, null);
                }else
                {
                    throw new FlexiException("There is no property with the name " + detailName);
                }
            }
        }


                    [Persistence.DoNotCopy]
        private int id;
        /// <summary>Gets or sets item ID.</summary>
        [Key]
        [ScaffoldColumn(false)]
        public virtual int ID
        {
            get { return id; }
            set { id = value; }
        }

        public override bool Equals(object obj)
        {
            if (this == obj) return true;
            PersistenceItem other = obj as PersistenceItem;
            return other != null && id != 0 && id == other.id;
        }

        int? hashCode;

        public override int GetHashCode()
        {
            if (!hashCode.HasValue)
                hashCode = (id > 0 ? id.GetHashCode() : base.GetHashCode());
            return hashCode.Value;
        }

        /// <summary>Returns this item's name.</summary>
        /// <returns>The item's name.</returns>
        public override string ToString()
        {
            return "#" + ID.ToString();
        }
    }
}
